/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package loganalysis;

import java.io.*;
//import java.text.DateFormat;
import java.util.*;
import java.util.Date.*;
import java.text.SimpleDateFormat;

/**
 *
 * @author prateekpatil
 */
public class LogsIntermediateData {
    
    private ArrayList<ArrayList<String>> logData ;
    private BufferedReader loadLogFile;
    private int numOfTasks;
    private int numOfWorkers;
    private Set workersInJob;
   // private int [] totalTime;
    private static BufferedReader loadInputFile;
    private long timeMS;
    private String timeStampOfData;
    private long averageExecTime;
    private String minExecutionTimeStamp;
    private String maxExecutionTimeStamp;
    private int avgWaitQueueTime;
    
    //Main Function
     public static void main(String[] args)  {
         
         
         LogsIntermediateData obj = new LogsIntermediateData();
         //Take input as txt file which contains path of input file and genrate the intermidate data 
         try{
         loadInputFile  = new BufferedReader(new FileReader ("List.txt"));
        
         }catch(FileNotFoundException e )
         {
         System.err.println("Error in List.txt : "+e);
         }
         String filePath = "";
        
         //ArrayList <String> arrayOfFilePath = new ArrayList<String>();
         //Loop for filePath
         try{
            //Initiaitng intermidiateData object 
            FileWriter intermidiateData = new FileWriter ("graph.txt" ,false);
            BufferedWriter fileForGraph = new BufferedWriter(intermidiateData); 
//                fileForGraph.write("timeStampOfData TimeinMS averageExecTime NumOfWorkers MaxExecTimeStamp MinExecTimeStamp NumofTasks");
//                fileForGraph.newLine();
                while ((filePath=loadInputFile.readLine())!=null)
                    {
                        
                        System.out.println("--------------------------");
                        System.out.println("File location is  "+filePath);
                        obj.ScanData(filePath);
                        try{
                              if(obj.CheckEmptyFile())
                              {
                                obj.CalculateTime();
                                obj.setNumOfTasks();
                                System.out.println("Rows Cured "+obj.Curration());
                                System.out.println(obj.getNumOfTasks());
                              // fileForGraph.write(obj.getTimeStampOfData()+" ");
                               fileForGraph.write(obj.getTimeMS()+" ");
                               obj.AverageExecutionTime();
                               fileForGraph.write(obj.getAverageExecTime()+" "); 
                                obj.NumberOfWorkers();
                               fileForGraph.write(obj.numOfWorkers+" "); 
                                obj.MaxExecution();
                               fileForGraph.write(obj.getMaxExecutionTimeStamp()+" "); 
                                obj.MinExecution();
                               fileForGraph.write(obj.getMinExecutionTimeStamp()+" ");
                                System.out.println(obj.numOfTasks);
                               fileForGraph.write(Integer.toString(obj.numOfTasks));
                               fileForGraph.newLine();
                              }
                        }catch(IndexOutOfBoundsException e)
                        {
                        System.err.println("File is empty "+e);
                        }
                        
                        System.out.println("--------------------------");
        
                      
                    }
                fileForGraph.close();
         }
         catch(IOException e)
         {
             System.err.println("Error in generating parameters : "+e);
         }
        
        // Tesing region 
//        Iterator list = obj.logData.iterator();
//        while(list.hasNext())
//        {
//            System.out.println(list.next());
//        }                   
       
    }
    public void ScanData(String filePath)
       {
            String fullFilePath = filePath;
            String line ="";
            //2D Array
         logData = new ArrayList<ArrayList<String>>();
             //Create file object and read it 
            try {
            loadLogFile= new BufferedReader(new FileReader (fullFilePath));
                }
            catch(FileNotFoundException e)
                {
                    System.err.println("Error in finding log file: "+e);
                }
        //Initialize Row and column counter
         int row = 0;
         int col = 0;
         //Nested Loops to read file 
         try{
         while( (line = loadLogFile.readLine())!=null)
         {
             Scanner scanLine = new Scanner(line);
             logData.add(new ArrayList<String>());
             while(scanLine.hasNext())
             {
                 logData.get(row).add(scanLine.next());
                 col++;
             }
             row++;
         }
         //this.numOfTasks = row-1;
        //System.out.println("Value of number of Rows "+this.numOfTasks);
         }
         catch(IOException e)
         {
             System.err.println("Error in reading logs: "+e);
         }
     
      
         //ArrayList<String> ar = logData.get(numOfTasks);
         
       } 
    public boolean CheckEmptyFile ()
    {
    
        if(logData.get(0).get(0).isEmpty())
        {
        return false;
        }
        else
        {
        return true;
        }
    }
    
    public void CalculateTime()
    {
        //Function to calculate the current time from epoch time on the log.
        timeMS = Long.parseLong((logData.get(1).get(2)).replace("ms", ""));
        timeStampOfData =  this.EpochTimeCalculator(timeMS);
        System.out.println("Time Stamp Of Data "+timeStampOfData);
         
        //Removing the Top two rows 
         logData.remove(0);
         logData.remove(0);
         
         
         
     }

    public int Curration()
    {
       int cured =0;
       int k = logData.size();
       ArrayList<String> remove;
       for (int i =0;i<k;i++)
       {    
        //   System.out.println("Row is "+ i);
         //  System.out.println(logData.get(i));
             try{
               for(int j =0;j<12;j++){
               if(logData.get(i).get(j).toString()==null)
                        {
                        //call code to curate the tmp file
                        }
                   }
                   }catch(IndexOutOfBoundsException e)
                   {
                   System.out.println("Error in line " + e);
                   System.out.println("Index of Row "+i);
                   logData.remove(i);
                   cured++;
                   }
       
           
       }
       return cured;
    }
    
    public void NumberOfWorkers()
    {
         //Function to find the number of workers (CPUs used)..inserted into the set
         workersInJob = new HashSet();
         for (int i =0;i<logData.size();i++)
         {
         String workers=logData.get(i).get(2);
         String [] token = workers.split(":");
         workersInJob.add(token[0]);
         }
         //Number of Workers
         numOfWorkers = workersInJob.size();
         System.out.println(numOfWorkers);
    }
    
    public void AverageExecutionTime()
    {
         //Calculate average complition 
         //Total time 
         long totalTimeSum = 0;
         int myNumofTask = logData.size();
         System.out.println("Num of Task in Average "+myNumofTask);
        // int [] totalTime = new int [myNumofTask];
         for (int i =0 ; i<myNumofTask; i++)
         {
             //[i]= Integer.parseInt(logData.get(i).get(10));
             //execTime.add(Integer.parseInt(logData.get(i).get(10)));
             totalTimeSum+= Integer.parseInt(logData.get(i).get(10));
            // int y = Integer.parseInt(logData.get(i).get(10));
             //totalTimeSum+ = y;
         }
         System.out.println("Total Execution Time "+totalTimeSum);
          //Average complition time of flocks of task
         averageExecTime = totalTimeSum/myNumofTask;
         System.out.println("Average complition time  "+averageExecTime);
    }

    public void MinExecution()
    {
             Long exectime[] = new Long [logData.size()];
             for (int i =0 ; i<logData.size(); i++)
                {
                    exectime[i]= Long.valueOf(logData.get(i).get(4));
                    
                }
            Arrays.sort(exectime);
            //Min Execution time
            minExecutionTimeStamp = this.EpochTimeCalculator(timeMS+exectime[0]);
            System.out.println("Min Exec Time Stamp "+minExecutionTimeStamp);
            
    }
    public void MaxExecution()
    {
             Long exectime[] = new Long [logData.size()];
             for (int i =0 ; i<logData.size(); i++)
                {
                    exectime[i]= Long.valueOf(logData.get(i).get(4));
                    
                }
            Arrays.sort(exectime);
            //Max execution time
            maxExecutionTimeStamp = this.EpochTimeCalculator(timeMS+exectime[(logData.size())-1]);
            System.out.println("Max Exec Time Stamp"+maxExecutionTimeStamp);
    }
    
    public String EpochTimeCalculator(Long time)
    {
         Date epoch = new Date(time);
         SimpleDateFormat fDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
         String actualDate = fDate.format(epoch);
         return actualDate;
    }
    
    public long AverageW8QTime()
    {
    
    return 10;
    }

    public BufferedReader getLoadLogFile() {
        return loadLogFile;
    }

    public void setLoadLogFile(BufferedReader loadLogFile) {
        this.loadLogFile = loadLogFile;
    }

    public ArrayList<ArrayList<String>> getLogData() {
        return logData;
    }

    public void setLogData(ArrayList<ArrayList<String>> logData) {
        this.logData = logData;
    }

    public int getNumOfTasks() {
        return numOfTasks;
    }

    public void setNumOfTasks() {
       
         this.numOfTasks = logData.size();
    }

    public int getNumOfWorkers() {
        return numOfWorkers;
    }

    public void setNumOfWorkers(int numOfWorkers) {
        this.numOfWorkers = numOfWorkers;
    }

    public Long getTimeMS() {
        return timeMS;
    }

    public void setTimeMS(Long timeMS) {
        this.timeMS = timeMS;
    }

    public Set getWorkersInJob() {
        return workersInJob;
    }

    public void setWorkersInJob(Set workersInJob) {
        this.workersInJob = workersInJob;
    }

      public void setTimeMS(long timeMS) {
        this.timeMS = timeMS;
    }

    public String getTimeStampOfData() {
        return timeStampOfData;
    }

    
    public long getAverageExecTime() {
        return averageExecTime;
    }

    public String getMaxExecutionTimeStamp() {
        return maxExecutionTimeStamp;
    }

    public String getMinExecutionTimeStamp() {
        return minExecutionTimeStamp;
    }

    
    
    
}
